package com.twg.servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.twg.util.UploadHelper;

public class UploadServlet extends HttpServlet {

	/**
	 * Constructor of the object.
	 */
	public UploadServlet() {
		super();
		System.out.println("<<<实例化>>>");
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
		System.out.println("<<<destroy>>>");
	}

	/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//得到上传文件的保存目录，将上传的文件存放于WEB-INF目录下，不允许外界直接访问，保证上传文件的安全
		String savePath = this.getServletContext().getRealPath(UploadHelper.FILEPATH);
		//上传时生成的临时文件保存目录
		String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
		String message = "上传成功.";
		File tempFile = new File(tempPath);
		File saveFile = new File(savePath);
		//判断目录是否存在
		if(!tempFile.exists() && !tempFile.isDirectory()){
			//创建临时目录
			tempFile.mkdir();
		}
		if(!saveFile.exists() && !saveFile.isDirectory()){
			saveFile.mkdir();
		}
		//存放字段value
		Map<String,String> fieldMap = new HashMap<String,String>();
		//使用Apache文件上传组件处理文件上传步骤：
		try {
			//1、创建一个DiskFileItemFactory工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			//设置工厂的缓冲区的大小，当上传的文件大小超过缓冲区的大小时，就会生成一个临时文件存放到指定的临时目录当中。
			//设置缓冲区的大小为100KB，如果不指定，那么缓冲区的大小默认是10KB
			factory.setSizeThreshold(1024*10);
			//设置上传时生成的临时文件的保存目录
			factory.setRepository(tempFile);
			//2、创建一个文件上传解析器
			ServletFileUpload upload = new ServletFileUpload(factory);
			//
			upload.setProgressListener(new ProgressListener() {
				@Override
				public void update(long arg0, long arg1, int arg2) {
					// TODO Auto-generated method stub
					System.out.println("文件大小:" + arg1 + ",已完成：" + arg0);
				}
			});
			upload.setHeaderEncoding("UTF-8");
			//设置上传单个文件的大小的最大值，目前是设置为1024*1024字节，也就是1MB
			upload.setFileSizeMax(1024*1024*10);
			//设置上传文件总量的最大值，最大值=同时上传的多个文件的大小的最大值的和，目前设置为100MB
			upload.setSizeMax(1024*1024*100);
			//4、使用ServletFileUpload解析器解析上传数据，解析结果返回的是一个List<FileItem>集合，每一个FileItem对应一个Form表单的输入项

			List<FileItem> list = upload.parseRequest(request);
			for (FileItem fileItem : list) {
				if(fileItem.isFormField()){//处理普通表单
					//获取字段名称和值
					String name = fileItem.getFieldName();
					String value = fileItem.getString("UTF-8");
					if(null==fieldMap.get(name)){
						fieldMap.put(name, value);	
					}else{
						fieldMap.put(name, fieldMap.get(name)+","+fileItem.getString("UTF-8"));
					}
				}else{//文件上传表单
					//获取字段名称和文件名称
					String name = fileItem.getFieldName();
					String fileName = fileItem.getName();
					if(fileName.trim().equals("") || fileName == null){
						continue;
					}
					//处理获取到的上传文件的文件名的路径部分，只保留文件名部分
					fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
					//得到上传文件的扩展名
					String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
					//得到新名称，防止重名覆盖 
					fileName = UploadHelper.makeFileName(fileName);
					//上传文件
					fieldMap.put(name, fileName);
					fileItem.write(new File(saveFile + "/" + fileName));
					message = "上传成功.";
				}
			}
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			message = "上传失败";
			System.out.println("获取表单集合异常：" + e);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			message = "上传失败.";
			System.out.println("上传失败：" + e);
		}
		request.setAttribute("message", message);
		request.getRequestDispatcher("../Result.jsp").forward(request, response);
	}

	/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		System.out.println("<<<doPost>>>");
		doGet(request,response);
	}

	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		// Put your code here
		System.out.println("<<<init>>>");
	}

}
